package activities;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.json.JSONArray;
import org.json.JSONException;

import helper.FBHelper;
import helper.GetFBUserPhotoHelper;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.facebook.Response;
import com.matchcalendar.R;

import dataFormat.FBUser;

public class PickFriendsActivity extends Activity {
	private Button imageButtonPrevious, buttonDone;
	private EditText editTextSearchFriends;
	private ListView listViewFriends;
	private List<FBUser> friendList = new ArrayList<FBUser>();
	private List<FBUser> displayFriendList = new ArrayList<FBUser>();
	private boolean haveTouched = false;
	private Set<String> isCheckedLastTime = new HashSet<String>();
	private Set<FBUser> isChecked = new HashSet<FBUser>();
	private SparseArray<View> findRow = new SparseArray<View>();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
		setContentView(R.layout.activity_pick_friends);
		findView();
		setListenerOrAdapter();
		initIsCheckedLastTime();
		new GetFriendsHelper().ensureSessionOpenAndDoSomething(PickFriendsActivity.this);
	}

	private void findView() {
		imageButtonPrevious = (Button) findViewById(R.id.imageButtonPrevious);
		buttonDone = (Button) findViewById(R.id.buttonDone);
		editTextSearchFriends = (EditText) findViewById(R.id.editTextSearchFriends);
		listViewFriends = (ListView) findViewById(R.id.listViewFriends);
	}

	private void setListenerOrAdapter() {
		imageButtonPrevious.setOnClickListener(new ImageButtonPreviousClick());
		listViewFriends.setOnItemClickListener(new ListViewFriendsItemClick());
		editTextSearchFriends.setOnTouchListener(new EditTextSearchFriendsTouch());
		editTextSearchFriends.addTextChangedListener(new EditTextSearchFriendsTextChanged());
		buttonDone.setOnClickListener(new ButtonDoneClick());
	}

	private class ImageButtonPreviousClick implements ImageButton.OnClickListener {

		@Override
		public void onClick(View v) {
			PickFriendsActivity.this.finish();
		}
	}
	
	private class ListViewFriendsItemClick implements ListView.OnItemClickListener {

		@Override
		public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) {
			ImageView imageViewCheck = (ImageView)view.findViewById(R.id.imageViewCheck);
			
			if (isChecked.contains(displayFriendList.get(position))) {
				imageViewCheck.setImageResource(R.drawable.com_facebook_button_check_off);
				isChecked.remove(displayFriendList.get(position));
			}
			else {
				imageViewCheck.setImageResource(R.drawable.com_facebook_button_check_on);
				isChecked.add(displayFriendList.get(position));
			}
		}
	}
	
	private class EditTextSearchFriendsTouch implements EditText.OnTouchListener {

		@Override
		public boolean onTouch(View view, MotionEvent event) {
			if (!haveTouched && event.getAction() == MotionEvent.ACTION_DOWN)
				((EditText)view).setText("");
			return false;
		}
	}
	
	private class EditTextSearchFriendsTextChanged implements TextWatcher {

		@Override
		public void afterTextChanged(Editable searchText) {
			if (haveTouched) {
				displayFriendList.clear();
				for (FBUser fbUser: friendList) {
					if (fbUser.getName().toLowerCase().contains(searchText.toString().toLowerCase()))
						displayFriendList.add(fbUser);
				}
				findRow.clear();
				((FriendsAdapter)listViewFriends.getAdapter()).notifyDataSetChanged();
				listViewFriends.setSelectionFromTop(0, 0);
			}
			else
				haveTouched = true;
		}

		@Override
		public void beforeTextChanged(CharSequence s, int start, int count, int after) {
		}

		@Override
		public void onTextChanged(CharSequence s, int start, int before, int count) {
		}
	}
	
	private class ButtonDoneClick implements Button.OnClickListener {

		@Override
		public void onClick(View v) {
			ArrayList<FBUser> friendList = new ArrayList<FBUser>();
			Bundle bundle = new Bundle();
			Intent intent = new Intent();
			
			for (FBUser fbUser: isChecked)
				friendList.add(fbUser);
			bundle.putParcelableArrayList("friendList", friendList);
			intent.putExtras(bundle);
			setResult(RESULT_OK, intent);
			PickFriendsActivity.this.finish();
		}
	}
	
	private void initIsCheckedLastTime() {
		Bundle bundle = getIntent().getExtras();
		
		for (String id: bundle.getStringArrayList("friendIdList"))
			isCheckedLastTime.add(id);
	}
	
	private class GetFriendsHelper extends FBHelper {
		private ProgressDialog proDialog;

		@Override
		protected void doAfterEnsureSessionOpen() {
			proDialog = ProgressDialog.show(PickFriendsActivity.this, "載入朋友名單", "正在載入朋友名單...");
			proDialog.setCancelable(false);
			fqlQuery("uid, name", "user", "uid in (select uid2 from friend where uid1 = me())", null,
					null, "name", null);
		}
		
		@Override
		protected void doAfterFqlQuery(Response response) {
			try {
				JSONArray dataJsonArr = response.getGraphObject().getInnerJSONObject().getJSONArray("data");
				
				for (int i=0; i<dataJsonArr.length(); i++) {
					String id = dataJsonArr.getJSONObject(i).getString("uid");
					String name = dataJsonArr.getJSONObject(i).getString("name");
					FBUser fbUser = new FBUser(id, name, null);
					
					if (isCheckedLastTime.contains(fbUser.getId()))
						isChecked.add(fbUser);
					friendList.add(fbUser);
					displayFriendList.add(fbUser);
				}
				listViewFriends.setAdapter(new FriendsAdapter(
						PickFriendsActivity.this, android.R.layout.simple_list_item_1, displayFriendList));
				proDialog.cancel();
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
	}
	
	private class FriendsAdapter extends ArrayAdapter<FBUser> {
		public FriendsAdapter(Context context, int textViewResourceId, List<FBUser> objects) {
			super(context, textViewResourceId, objects);
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			if (findRow.get(position) == null) {
				View row = getLayoutInflater().inflate(R.layout.custom_picture_text_choice_view, parent, false);
				TextView textViewName = (TextView)row.findViewById(R.id.textViewName);
				ImageView imageViewCheck = (ImageView)row.findViewById(R.id.imageViewCheck);
				
				textViewName.setText(getItem(position).getName());
				if (isChecked.contains(getItem(position)))
					imageViewCheck.setImageResource(R.drawable.com_facebook_button_check_on);
				else
					imageViewCheck.setImageResource(R.drawable.com_facebook_button_check_off);
				findRow.put(position, row);
				if (getItem(position).getPhoto() == null)
					new GetFriendPhotos().execute(getItem(position));
				else
					setPhoto(position);
				return row;
			}
			else if (getItem(position).getPhoto() == null)
				return findRow.get(position);
			else {
				setPhoto(position);
				return findRow.get(position);
			}
		}
		
		private void setPhoto(int position) {
			ImageView head = (ImageView)findRow.get(position).findViewById(R.id.imageViewHead);
			BitmapDrawable defaultHead =
					(BitmapDrawable) getResources().getDrawable(R.drawable.com_facebook_profile_default_icon);
			Bitmap defaultHeadBitMap = defaultHead.getBitmap();
			
			head.setImageBitmap(Bitmap.createScaledBitmap(
					getItem(position).getPhoto(), defaultHeadBitMap.getWidth(), defaultHeadBitMap.getHeight(), true));
		}
		
		private class GetFriendPhotos extends GetFBUserPhotoHelper {

			@Override
			protected void onPostExecute(FBUser fbUser) {
				FriendsAdapter.this.notifyDataSetChanged();
			}
		}
	}
}